package org.rajawali3d.util.egl;

import ohos.agp.render.opengl.EGL;
import ohos.agp.render.opengl.EGLConfig;
import ohos.agp.render.opengl.EGLDisplay;
import org.rajawali3d.view.IRajawaliEglConfigChooser;
import org.rajawali3d.view.ISurface;


public class RajawaliEGLConfigChooser implements IRajawaliEglConfigChooser {
    private ISurface.ANTI_ALIASING_CONFIG antiAliasingConfig;
    private static final int EGL_COVERAGE_BUFFERS_NV = 12512;
    private static final int EGL_COVERAGE_SAMPLES_NV = 12513;
    public static final int EGL_OPENGL_ES2_BIT = 4;
    public static final int EGL_OPENGL_ES3_BIT_KHR = 64;
    private int[] configSpec;
    private String errorText = "";
    int EGL_SAMPLE_BUFFERS = 0x3032;
    int EGL_SAMPLES = 0x3031;

    public RajawaliEGLConfigChooser(int glMajorVersion, ISurface.ANTI_ALIASING_CONFIG antiAliasingConfig
            , int sampleCount, int bitsRed, int bitsGreen, int bitsBlue, int bitsAlpha, int bitsDepth) {
        this.antiAliasingConfig = antiAliasingConfig;

        switch (antiAliasingConfig) {
            case MULTISAMPLING:
                int a1 = configSupportsMultiSampling() ? 1 : 0;
                int a2 = configSupportsMultiSampling() ? sampleCount : 0;
                configSpec = new int[]{EGL.EGL_RED_SIZE,
                        bitsRed,
                        EGL.EGL_GREEN_SIZE,
                        bitsGreen,
                        EGL.EGL_BLUE_SIZE,
                        bitsBlue,
                        EGL.EGL_ALPHA_SIZE,
                        bitsAlpha,
                        EGL.EGL_DEPTH_SIZE,
                        bitsDepth,
                        EGL.EGL_RENDERABLE_TYPE,
                        EGL_OPENGL_ES2_BIT,
                        EGL_SAMPLE_BUFFERS,
                        /* Do we use sample buffers */
                        a1,
                        EGL_SAMPLES,
                        /* Sample count */
                        a2,
                        EGL.EGL_NONE};
                break;
            case COVERAGE:
                configSpec = new int[]{
                        EGL.EGL_RED_SIZE,
                        bitsRed,
                        EGL.EGL_GREEN_SIZE,
                        bitsGreen,
                        EGL.EGL_BLUE_SIZE,
                        bitsBlue,
                        EGL.EGL_ALPHA_SIZE,
                        bitsAlpha,
                        EGL.EGL_DEPTH_SIZE,
                        bitsDepth,
                        EGL.EGL_RENDERABLE_TYPE,
                        EGL_OPENGL_ES2_BIT,
                        EGL_COVERAGE_BUFFERS_NV,
                        1,
                        EGL_COVERAGE_SAMPLES_NV,
                        2,
                        EGL.EGL_NONE
                };
                break;
            default:
                configSpec = new int[]{
                        EGL.EGL_RED_SIZE,
                        bitsRed,
                        EGL.EGL_GREEN_SIZE,
                        bitsGreen,
                        EGL.EGL_BLUE_SIZE,
                        bitsBlue,
                        EGL.EGL_ALPHA_SIZE,
                        bitsAlpha,
                        EGL.EGL_DEPTH_SIZE,
                        bitsDepth,
                        EGL.EGL_RENDERABLE_TYPE,
                        EGL_OPENGL_ES2_BIT,
                        EGL.EGL_NONE
                };
                break;
        }
        if (glMajorVersion > 2) {
            configSpec[11] = 0x0040;
        }
    }

    private boolean configSupportsMultiSampling() {
        return antiAliasingConfig == ISurface.ANTI_ALIASING_CONFIG.MULTISAMPLING;
    }

    @Override
    public ResultConfigChooser chooseConfigWithReason(EGL var1, EGLDisplay var2) {
        EGLConfig config = chooseConfig(var1, var2);
        return new ResultConfigChooser(config, this.errorText);
    }

    @Override
    public EGLConfig chooseConfig(EGL egl, ohos.agp.render.opengl.EGLDisplay display) {
        int[] result = new int[1];
        if (!egl.eglChooseConfig(display, configSpec, null, 0, result)) {
            errorText = "This device does not support the requested EGL Configuration!" + antiAliasingConfig.name();
        }
        EGLConfig[] configs = new EGLConfig[result[0]];
        if (!egl.eglChooseConfig(display, this.configSpec, configs, result[0], result)) {
            this.errorText = "Couldn't create EGL configuration.";
        }
        int[] value = new int[1];
        for (EGLConfig config : configs) {
            egl.eglGetConfigAttrib(display, config, EGL.EGL_RED_SIZE, value);
            if (value[0] == configSpec[1]) {
                return config;
            }
        }
        return null;
    }
}
